/* Use standard I/O  */
#include "File.h"
/**
* @todo list:input the Bin file,and then output the Bin file's data and length.
* @description: This program is used to read the data and length of a binary file who is MCU's firmware.
* @author: 52-Hz
* @date: 2024-12-06
* @version: 1.0.0
* @todo： 1.add more check.
*/

#define PACKET_MAX_SZIE   64
int get_file_length(FILE *filename, unsigned int *length);

int File_parse(char *filename,char *slot,BinFileInfo *o_binfile_info)
{
    int ret = false;
    //1.check whether the input's parameter illegal or not. need to add more check.
    if ((filename == NULL) || (slot == NULL))
    {
        fprintf(stderr, "filename is NULL, parameter error! \r\n");
        exit(EXIT_FAILURE); //exit with error code. EXIT_FAILURE means the program terminated abnormally.
    }
    //2.open the file.
    if ((o_binfile_info->filePointer = fopen(filename, "rb")) == NULL)  //"rb" means read binary file.
    {
        perror("can't open file");
        exit(EXIT_FAILURE);
    }
    //3.read the file's information.e.g. data and length.
    //3.1 get the length of the file.
    get_file_length(o_binfile_info->filePointer,&o_binfile_info->fileLength);//get the length of the file.
    o_binfile_info->slot = slot; //store the slot number of the file.

    //3.2 read the file's data and store it in the struct BinFileInfo's buffer.
    o_binfile_info->fileBuffer = (unsigned char*)malloc((o_binfile_info->fileLength) * sizeof(unsigned char)); //allocate memory for the file's data.
    fread(o_binfile_info->fileBuffer, 1,o_binfile_info->fileLength, o_binfile_info->filePointer);
    //4. fsync to ensure that the data is written to the disk.
    fsync(fileno(o_binfile_info->filePointer));

    ret = true;
    return ret;
}

int File_close(BinFileInfo *bin_file_info)
{
    int ret = false;
    //1.check whether the input's parameter illegal or not. need to add more check.
    if (bin_file_info == NULL)
    {
        fprintf(stderr, "bin_file_info is NULL, parameter error! \r\n");
        exit(EXIT_FAILURE); //exit with error code. EXIT_FAILURE means the program terminated abnormally.
    }
    //2.close the file.
    if(fclose(bin_file_info->filePointer) != 0) //close the file.
    {
        perror("can't close file");
        exit(EXIT_FAILURE);
    }
    ret = true;
    //3. for debug.
#if 0    
    printf("\nThe length of the file is %d \r\n", bin_file_info->fileLength);
    //display the part of the file's data.
    
    for(int i=0;i<4;i++){
        for(int j=0;j<16;j++){
            printf("[%2x]:%02x ",j+i*16,bin_file_info->fileBuffer[j+i*16]);
        }
        printf("\r\n");
    }
#endif 
    //4. free the memory.
    free(bin_file_info->fileBuffer);
    return ret;
}

int get_file_length(FILE *filename, unsigned int *length)
{
    int ret = false;
    fseek(filename, 0, SEEK_END); //move the file pointer to the end of the file.
    *length = ftell(filename); //get the current position of the file pointer, which is the length of the file.
    fseek(filename, 0, SEEK_SET); //move the file pointer to the beginning of the file.
    ret = true;

    return ret;
}